package com.gkt.ec.cms.activity.task;

import com.gkt.ec.cms.activity.AppConstant;
import com.gkt.ec.cms.activity.model.domain.CustomerActivityEntity;
import com.gkt.ec.cms.activity.model.domain.MarketActivityEntity;
import com.gkt.ec.cms.activity.service.ActivityService;
import com.gkt.ec.cms.task.SendSmsTaskManager;

import org.apache.shiro.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;

/**
 * @author Huzl
 * @version 1.0.0
 */
@Component
public class SendActivitySmsTaskManager extends SendSmsTaskManager {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private ActivityService activityService;

    private TaskStatusCallback taskStatusCallback = new TaskStatusCallbackImpl();

    private Map<Long, SendSmsTask> tasks = new ConcurrentHashMap<Long, SendSmsTask>();

    /**
     * 系统启动，初始化加载所有待发送的活动短信发送任务
     */
    @PostConstruct
    public void init() {
        List<MarketActivityEntity> activityList = activityService.querySendSmsActivity();
        int count = CollectionUtils.size(activityList);
        logger.info("SendActivitySmsTaskManager init begin, activity count:{}", count);
        if (count == 0) return;
        for (MarketActivityEntity anActivityList : activityList) {
            addActivity(anActivityList);
        }
        logger.info("SendActivitySmsTaskManager init end");
    }

    /**
     * 添加活动短信任务
     */
    public void addActivity(MarketActivityEntity activityEntity) {

        SendSmsTask task = new SendSmsTask(activityEntity, taskStatusCallback, activityService);
        task.setSmsSender(smsSender);
        task.setSendSmsExecutor(scheduledExecutorService);
        long delaySeconds = getDelaySeconds(activityEntity);
        logger.info("SendActivitySmsTaskManager addActivity activityId:{},name:{},delaySeconds:{}", activityEntity.getId(),
                activityEntity.getActivityName(), delaySeconds);
        ScheduledFuture scheduledFuture = scheduledExecutorService.schedule(task, delaySeconds, TimeUnit.SECONDS);
        task.setScheduledFuture(scheduledFuture);
    }

    private long getDelaySeconds(MarketActivityEntity activityEntity) {
        long delay;
        if (activityEntity.getSmsSendType() == AppConstant.SmsSendType.IMMEDIATE)
            delay = 0;
        else
            delay = (activityEntity.getSmsSendTime().getTime() - System.currentTimeMillis()) / 1000;
        return delay > 0 ? delay : 0;
    }

    /**
     * 取消活动短信发送任务
     */
    public void cancelActivity(Long activityId) {
        logger.info("SendActivitySmsTaskManager cancelActivity activityId:{}", activityId);
        SendSmsTask smsTask = tasks.remove(activityId);
        if (smsTask != null) {
            smsTask.cancel();
        }
    }

    class TaskStatusCallbackImpl implements TaskStatusCallback {
        public void beginTask(Long activityId) {
            logger.info("SendActivitySmsTaskManager beginTask activityId:{}", activityId);
            activityService.updateSendSmsActivityStatus(activityId, AppConstant.SendSmsStatus.BEGIN, new Date(), null);
        }

        public void sentSms(Long activityId, CustomerActivityEntity customerActivityEntity, boolean success) {
            logger.info("SendActivitySmsTaskManager sentSms,result:{} activityId:{},recId:{},tel:{}", success, activityId,
                    customerActivityEntity.getId(), customerActivityEntity.getCustomerTel());
            activityService.updateSendSmsCustomerStatus(customerActivityEntity.getId(),
                    success ? AppConstant.SendSmsStatus.SEND_OK : AppConstant.SendSmsStatus.SEND_FAIL, new Date());
        }

        public void endTask(Long activityId) {
            logger.info("SendActivitySmsTaskManager endTask activityId:{}", activityId);
            tasks.remove(activityId);
            activityService.updateSendSmsActivityStatus(activityId, AppConstant.SendSmsStatus.END, null, new Date());
        }
    }

}
